package config

import (
	"log"
	"os"
	"path/filepath"
	"ruoyi-go-echo-ddd/internal/infrastructure/utils"
	"sync"

	"github.com/natefinch/lumberjack"
	"github.com/rs/zerolog"
)

// ZeroLog zero 全局日志
var ZeroLog zerolog.Logger

var zeroOnce = sync.OnceValue(func() error {
	dateTimeFormat := "2006-01-02 15:04:05.000"

	currentPath, err := utils.GetCurrentPath()
	if err != nil {
		log.Printf("获取当前目录错误: %v", err)
		return err
	}

	logDir := "logs"

	log.Printf("获取当前目录: %s", currentPath)
	if currentPath == "/" {
		logDir = filepath.Join("app", "logs")
	}
	// 构建日志目录路径
	log.Printf("zero日志目录: %s", logDir)
	// 如果日志目录不存在，则创建
	if err := os.MkdirAll(logDir, os.ModePerm); err != nil {
		log.Printf("创建日志目录失败: %v,路径===%s", err, logDir)
		return err
	}

	// 构建日志文件路径
	logFileName := filepath.Join(logDir, "ry-go-echo-zero.log")

	// 日志输出配置, 借助 lumberjack 完成日志切割
	lumberjackLogger := &lumberjack.Logger{
		Filename:   logFileName, // 日志文件名
		MaxSize:    5,           // 最大日志大小（MB）
		MaxAge:     30,          // 最大存在天数
		MaxBackups: 30,          // 最大备份数量
		Compress:   false,       // 是否压缩
	}

	// 文件日志输出，json格式
	//fileWriter := zerolog.MultiLevelWriter(zerolog.SyncWriter(lumberjackLogger))
	// 文件日志输出（文本格式）
	fileWriter := zerolog.ConsoleWriter{
		Out:        lumberjackLogger,
		TimeFormat: dateTimeFormat,
		NoColor:    true, // 文件日志不需要颜色
	}
	// 控制台日志输出（带颜色）
	consoleWriter := zerolog.ConsoleWriter{
		Out:        os.Stdout,
		TimeFormat: dateTimeFormat,
		NoColor:    false, // 启用颜色
	}

	// 多路复用器，同时输出到文件和控制台
	multiWriter := zerolog.MultiLevelWriter(fileWriter, consoleWriter)

	// 初始化 ZeroLogger，添加请求日志钩子
	ZeroLog = zerolog.New(multiWriter).
		With().
		Timestamp().
		Caller().
		Logger().
		Level(zerolog.DebugLevel) // 设置日志级别为 Debug

	// 设置全局 ZeroLogger
	zerolog.DefaultContextLogger = &ZeroLog
	zerolog.TimeFieldFormat = dateTimeFormat

	abs, err := filepath.Abs(lumberjackLogger.Filename)
	if err != nil {
		return err
	}
	// 打印当前日志文件路径
	log.Printf("当前zerolog文件===%s", abs)
	return nil
})

// ZeroInit zero日志配置初始化
func ZeroInit() error {
	return zeroOnce()
}
